package com.hzgj.soa.protocol.pb.data;

import com.baidu.bjf.remoting.protobuf.annotation.Protobuf;
import com.hzgj.bcl.soa.rpc.exception.Exceptions;
import com.hzgj.bcl.soa.rpc.exception.FaultException;
import com.hzgj.bcl.soa.rpc.exception.RpcException;
import com.hzgj.bcl.soa.rpc.exception.RpcInfo;
import com.hzgj.bcl.util.lang.StrKit;
import com.hzgj.soa.protocol.pb.encode.SimpleEncoder;

public class ResponseMessage {

    public static ResponseMessage success(Object result) {
        ResponseMessage message = new ResponseMessage();
        message.serverTime = System.currentTimeMillis();
        message.success = true;
        message.result = SimpleEncoder.encode(result);
        return message;
    }

    public static ResponseMessage failed(Throwable e) {
        ResponseMessage message = new ResponseMessage();

        message.serverTime = System.currentTimeMillis();
        if (e instanceof RpcException) {
            message.errorCode = ((RpcException) e).getErrorCode();
        } else if (e instanceof FaultException) {
            message.errorCode = ((FaultException) e).getErrorCode();
        } else {
            message.errorCode = RpcInfo.SERVER_UNKNOWN_ERROR.value();
        }
        message.errorInfo = StrKit.isBlank(e.getMessage()) ? e.toString() : e.getMessage();
        message.errorDetail = Exceptions.getStackTrace(e);

        return message;
    }

    public static ResponseMessage failed(RpcInfo ec) {
        ResponseMessage message = new ResponseMessage();

        message.serverTime = System.currentTimeMillis();
        message.errorCode = ec.value();
        message.errorInfo = ec.description();

        return message;
    }

    /**
     * 是否成功
     */
    @Protobuf(order = 1, required = true)
    public boolean success;

    /**
     * 调用结果
     */
    @Protobuf(order = 2)
    public SimpleValue result;

    /**
     * 错误信息
     */
    @Protobuf(order = 3)
    public String errorInfo;

    /**
     * 服务器时间
     */
    @Protobuf(order = 4, required = true)
    public long serverTime;

    /**
     * 错误代码
     */
    @Protobuf(order = 6)
    public int errorCode;

    /**
     * 错误详情，如异常堆栈，一般只应该在 DEBUG 模式传播给客户端，便于快速调试
     */
    @Protobuf(order = 7)
    public String errorDetail;

    @Protobuf(order = 8, required = true)
    public Long messageId;
}


